﻿// 0827train03.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <limits>
#include <deque>

using namespace std;

/*
N个人围成一圈，按顺时针从1到N编号
编号为1的人从1开始喊数，下一个人喊的数字为上一个人的数字加1
数字是7的倍数 数字本身含有7的话
喊“过”
假定玩这个游戏的N个人都没有失误地在正确的时机喊了“过”
当喊到数字K时，可以统计每个人喊"过"的次数

现给定一个长度为N的数组，存储了打乱顺序的每个人喊"过"的次数
请把它还原成正确的顺序，即数组的第i个元素存储编号i的人喊“过”的次数

输入描述
输入为一行，为空格分隔的喊"过"的次数
注意K并不提供，K不超过200，而数字的个数即为N

输出描述
输出为一行，为顺序正确的喊"过"的次数，也由空格分隔

输入
0 1 0
输出
1 0 0

一共只有一次喊"过"，那只会发生在需要喊7时
按顺序，编号为1的人会遇到7，故输出1 0 0
注意，结束时的K不一定是7，也可以是8、9等，喊过的次数都是1 0 0
 */

class Solution01
{
public:
    bool checkNum(int num)
    {
        //数字是7的倍数 数字本身含有7
        if (num % 7 == 0) return true;
        string num_str = to_string(num);

        for (auto&oh_char:num_str)
        {
            if (oh_char == '7') return true;
        }
        return false;
    }
    Solution01(vector<int>&origin_vec)
    {
        int vec_size = origin_vec.size();

        //排序origin_vec
        sort(origin_vec.begin(), origin_vec.end());

        vector<int>train_vec(vec_size);
        /*
         数字num对应的索引为 (num-1)%n
         */
        int curr_num = 1;
        while (true)
        {
            vector<int>sort_train = train_vec;
            sort(sort_train.begin(), sort_train.end());
            if (sort_train == origin_vec)
            {
                break;
            }

            if (checkNum(curr_num))
            {
                int index = (curr_num - 1) % vec_size;
                train_vec[index] += 1;
            }
            curr_num += 1;
        }

        for (auto&num:train_vec)
        {
            cout << num << ' ';
        }

    }
};

/*
 对于一个连续正整数组成的序列，可以将其拼接成一个字符串，再将字符串里的部分字符打乱顺序

 如序列8 9 10 11 12，拼接成的字符串为89101112，打乱一部分字符后得到90811211，
 原来的正整数10就被拆成了0和1

现给定一个按如上规则得到的打乱字符的字符串，
请将其还原成连续正整数序列，
并输出序列中最小的数字

输入描述
输入一行，为打乱字符的字符串和正整数序列的长度，两者间用空格分隔，
字符串长度不超过200，正整数不超过1000，保证输入可以还原成唯一序列

输出描述
输出一个数字，为序列中最小的数字

示例1
输入
19801211 5
输出
8
说明
还原出的序列为 8 9 10 11 12，故输出 8
 */
class Solution02
{
public:
    Solution02(string&origin_num, int length)
    {
        sort(origin_num.begin(), origin_num.end());

        int start = 1;

        while (true)
        {
            string curr_num;
            for (int i=start; i<=start+length-1; i++)
            {
                curr_num += to_string(i);
            }

            string sort_curr = curr_num;
            sort(sort_curr.begin(), sort_curr.end());

            if (sort_curr==origin_num)
            {
                break;
            }

            start += 1;
        }

        cout << start;
        //Solution02
    }
};


/*
100个人围成一圈，每个人有一个编码，编号从1开始到100
他们从1开始依次报数，报到为M的人自动退出圈圈，
然后下一个人接着从1开始报数，直到剩余的人数小于M
请问最后剩余的人在原先的编号为多少？

输入描述
输入一个整数参数 M

输出描述
如果输入参数M小于等于1或者大于等于100，输出“ERROR!”；
否则按照原先的编号从小到大的顺序，以英文逗号分割输出编号字符串

输入
3
输出
58,91

输入
4
输出
34,45,97
 */
class Solution03
{
public:
    Solution03(int out_num)
    {
        vector<int>train_vec(100);
        for (int i=0; i<train_vec.size(); i++)
        {
            train_vec[i] = i + 1;
        }

        int start = 0;
        int count = 1;
        while (train_vec.size()>=out_num)
        {
            
            if (count==out_num)
            {
                //if (train_vec[start]==100)
                //{
                //    cout << 100;
                //}

                cout << train_vec[start] << endl;
                train_vec.erase(train_vec.begin() + start, train_vec.begin() + start+1);
                count = 1;

                if (start + 1 >= train_vec.size()) start = 0;

                continue;
            }
            if (start+1>=train_vec.size())
            {
                start = 0;
            }
            else
            {
                start += 1;
            }
            count += 1;
        }

        for (int i=0; i<train_vec.size(); i++)
        {
            cout << train_vec[i];
            if (i!=train_vec.size()-1)
            {
                cout << ',';
            }
        }

    }
};


int main()
{
	{
        int out_num = 4;
        Solution03 solu(out_num);

        /*
         1 2 3 4 5 6 7 8 9 10size10

		1 2 3 5 6 7 9 10 11 12
        
         */

        //vector<int>test = { 1,2,3 };
        //test.erase(test.begin(), test.begin() + 1);
        //for (auto&num:test)
        //{
        //    cout << num << ' ';
        //}

        return 0;
        //
	}
	{
        //19801211 5
        //string num_str = "19801211";
        //sort(num_str.begin(), num_str.end());
        //cout << num_str;
        //int length = 5;
        string num_str;
        cin >> num_str;
        int length;
        cin >> length;
        Solution02 solu(num_str, length);

        return 0;
	}
    vector<int>origin_num;
    //string input = "0 1 0";
    string input;
    getline(cin, input);
    stringstream oh_sstream(input);
    string token;
    while (oh_sstream>>token)
    {
        origin_num.push_back(stoi(token));
    }
    Solution01 solu(origin_num);
   
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
